package archer.application.core.service.system;

import archer.application.core.cache.RuleCache;
import archer.application.core.entity.system.Rule;
import archer.framework.common.annotation.ServiceOnly;
import archer.framework.common.repository.condition.QueryCondition;
import archer.application.core.service.BaseService;
import archer.framework.protocol.result.ExecuteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static archer.application.core.constant.Constant.RuleStatus.NEW;
import static archer.application.core.constant.Constant.RuleStatus.USED;

/**
 * @author Dendi
 * @date 16/7/4
 */
@Service
public class RuleService extends BaseService {

    @Autowired
    RuleCache ruleCache;

    /**
     * 新增/更新规则
     *
     * @param rule
     * @return
     */
    public ExecuteResult store(Rule rule) {

        if (isEmpty(rule.getType())) {
            throwParamNullException("规则类型不能为空");
        }

        if (isEmpty(rule.getCode())) {
            throwParamNullException("规则编码不能为空");
        }

        if (isEmpty(rule.getVal())) {
            throwParamNullException("规则不能为空");
        }

        if (rule.duplicated("code", asMap("type", rule.getType()))) {
            throwDataDuplicatedException(template("分组[${type}],编码[${code}]重复").bind(rule).toString());
        }

        rule.store();

        if (USED.equals(rule.getStatus())) {
            ruleCache.cache(rule);
        }

        return success();
    }

    /**
     * 分页查找所有规则
     *
     * @param queryCondition
     * @return
     */
    public ExecuteResult findPagedList(QueryCondition queryCondition) {

        return success(findPagedList(Rule.find.query(), queryCondition));
    }

    /**
     * 删除规则
     *
     * @param id
     * @return
     */
    public ExecuteResult delete(String id) {

        if (isEmpty(id)) {
            throwParamNullException("规则不能为空");
        }

        Rule rule = Rule.find.byId(id);

        if (isNotEmpty(rule)) {
            if (USED.equals(rule.getStatus())) {
                throwAccessDeniedException("不能删除已启用规则");
            }
            rule.logicalDelete();
        }

        return success();
    }

    /**
     * 删除多条规则
     *
     * @param ids
     * @return
     */
    public ExecuteResult deleteAll(List<String> ids) {

        if (isEmpty(ids)) {
            throwParamNullException("规则参数不能为空");
        }

        for (String each : ids) {
            this.delete(each);
        }

        return success();
    }

    /**
     * 启用规则
     *
     * @param id
     * @return
     */
    public ExecuteResult enable(String id) {

        if (isEmpty(id)) {
            throwParamNullException("规则不能为空");
        }

        Rule rule = Rule.find.byId(id);

        if (isNotEmpty(rule) && NEW.equals(rule.getStatus())) {
            rule.setStatus(USED).store();
            ruleCache.cache(rule);
        }

        return success();
    }

    /**
     * 启用规则
     *
     * @param ids
     * @return
     */
    public ExecuteResult enableAll(List<String> ids) {

        if (isEmpty(ids)) {
            throwParamNullException("规则不能为空");
        }

        for (String each : ids) {
            this.enable(each);
        }

        return success();
    }

    @ServiceOnly
    public <T> T getValue(String key) {
        Rule rule = ruleCache.getByCacheKey(key);
        if (rule == null) {
            return null;
        }
        return rule.getValue();
    }
}
